package com.company.Link;

/**
 * 我的链表
 * @author 关敬元
 * @Description
 * @date 2019/11/28
 */
//只有内部类能私有化，外部类不能私有化，没有意义
public class MyLink {

    private Entry link;//链表
    private int size; //记录链表的长度

    /**
     * 获取链表长度
     */
    public int getSize() {
        return size;
    }

    /**
     * 清除所有链
     */
    public void clear() {
        size = 0;
        link = null;
    }

    /**
     * 向链表的尾部添加一个环
     *
     * @param key
     * @param value
     */
    public void add(Object key, Object value) {
        //造一个环
        Entry cpnow = new Entry(key, value);
        //判断链表是否为空
        if (link == null) {
            //将建造出来的空环放在第一个位置
            link = cpnow;
        } else {
            //如果已经有N环了
            //先找到最后一环
            Entry last = link;
            while (last.getNext() != null) {
                last = last.getNext();
            }
            //先把最后一环的地址给空环的上一环地址
            cpnow.setPrev(last);
            //再把空环的地址赋给最后一环的下一环地址
            last.setNext(cpnow);

//                //把新环插入链表头部
//                //将空环的下一个环指向原第一环
//                cpnow.setNext(link);
//                //将原第一环的上一个环指向新环
//                link.setPrev(cpnow);
//                //把link指向第一环
//                link=cpnow;

            size++;
        }
    }

    public void remove(int pos) throws NullPointerException {
        if (pos >= size) {
            throw new NullPointerException("兄弟不要越界");
        }
        //删除首环
        if (pos == 0) {
            //删除首环
            //把首环的下一环的prev设置为null 并同时把link指向第二环
            link = link.getNext();
            link.setPrev(null);
        } else if (pos == size - 1) {
            //删除尾环
            Entry last = link;   //尾环indexOf(size-1)
            while (last.getNext() != null) {
                last = last.getNext();
            }
            last.getPrev().setNext(null);
        } else {
            //找到要删除中间的环
            Entry delEntry = link;
            for (int i = 0; i < pos; i++) {
                delEntry = delEntry.getNext();
            }
            //将删除环的上一环的next指向删除环的next
            delEntry.getPrev().setNext(delEntry.getNext());
            //将删除环的下一环的prev指向删除环的上一环
            delEntry.getNext().setPrev(delEntry.getPrev());
        }
        size--;
    }

    /**
     * 根据用户给的第pos环获得对应的Entry对象
     *
     * @return
     */
    public Entry indexOf(int pos) throws NullPointerException {
        if (pos >= size) {
            throw new NullPointerException("越界");
        }
        Entry last = link;
        for (int i = 0; i < pos; i++) {
            last = last.getNext();
        }
        return last;
    }

    /**
     * 替换中间的某一环
     *
     * @param pos
     * @param key
     * @param value
     */
    public void set(int pos, Object key, Object value) {
        //找到用户要替换的环
        Entry rep = indexOf(pos);
        //生成你的新环
        Entry newEntry = new Entry(key, value);
        //将替换环的上一环和下一环赋给新环的上一环和下一环
        newEntry.setPrev(rep.getPrev());
        newEntry.setNext(rep.getNext());
        //将替换环的上一环的下一环设置为新环
        rep.getPrev().setNext(newEntry);
        //将替换环的下一环的上一环设置为新环
        rep.getNext().setPrev(newEntry);
        //将替换环的上下换设置为null;
        rep.setNext(null);
        rep.setPrev(null);
    }

    /**
     * 此方法不是链表方法是HashMap方法
     *
     * @param key
     * @return
     */
    //根据键找一个值
    public Object get(Object key) {
        for (int i = 0; i < size; i++) {
            Entry temp = indexOf(i);
            if (temp.getKey() == key) {     //引用数据类型比地址（栈） ，基本数据类型比值
                return temp.getValue();  //多重循环的退出方式
            }
        }
        return null;
    }

    //内部类

    /**
     * 一个环
     */
    public class Entry {
        private Entry prev;//上一个环
        private Entry next;//下一个环
        private Object key;//键
        private Object value;//值

        public Entry(Object key, Object value) {
            this.key = key;
            this.value = value;
        }

        public Entry getPrev() {
            return prev;
        }

        public void setPrev(Entry prev) {
            this.prev = prev;
        }

        public Entry getNext() {
            return next;
        }

        public void setNext(Entry next) {
            this.next = next;
        }

        public Object getKey() {
            return key;
        }

        public void setKey(Object key) {
            this.key = key;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }
    }
    public static void main(String[] args) {
        MyLink ml = new MyLink();
        ml.add(1,100);
        ml.add("aaa","111");
        ml.add(444,new Object());
        ml.add(53.6,"帅");
        System.out.println(123);
    }
}

